<!--
 * Tencent is pleased to support the open source community by making BK-JOB生物智算平台 available.
 *
 * Copyright (C) 2021 THL A29 Limited, a Tencent company.  All rights reserved.
 *
 * BK-JOB生物智算平台 is licensed under the MIT License.
 *
 * License for BK-JOB生物智算平台:
 *
 *
 * Terms of the MIT License:
 * ---------------------------------------------------
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
 * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
 * the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
-->

<template>
  <div class="executive-history-page">
    <list-action-layout>
      <jb-search-select ref="search" :data="searchSelect" :placeholder="$t('history.搜索任务ID，任务名称，执行方式，任务类型，任务状态，执行人...')"
        style="width: 600px;" @on-change="handleSearch" />
      <template #right>
        <bk-date-picker ref="datePicker" :clearable="false" :placeholder="$t('history.选择日期')" shortcut-close
          :shortcuts="shortcuts" type="datetimerange" up-to-now use-shortcut-text :value="defaultDateTime"
          @change="handleDateChange" />
      </template>
    </list-action-layout>
    <render-list ref="list" v-test="{ type: 'list', value: 'execHistory' }" class="executive-history-table"
      :data-source="fetchExecutionHistoryList" :search-control="() => $refs.search" :size="tableSize">
      <bk-table-column v-if="allRenderColumnMap.id" key="id" align="left" label="ID" prop="id" width="130">
        <template slot-scope="{ row }">
          <auth-button auth="task_instance/view" :permission="row.canView" :resource-id="row.id" text
            @click="handleGoDetail(row)">
            {{ row.id }}
          </auth-button>
        </template>
      </bk-table-column>
      <bk-table-column v-if="allRenderColumnMap.name" key="name" align="left" :label="$t('history.任务名称.colHead')"
        min-width="200" prop="name" show-overflow-tooltip />
      <bk-table-column v-if="allRenderColumnMap.startupModeDesc" key="startupModeDesc" align="left"
        :label="$t('history.执行方式.colHead')" prop="startupModeDesc" width="120" />
      <bk-table-column v-if="allRenderColumnMap.typeDesc" key="typeDesc" align="left"
        :label="$t('history.任务类型.colHead')" prop="typeDesc" width="140" />
      <bk-table-column v-if="allRenderColumnMap.statusDesc" key="statusDesc" align="left"
        :label="$t('history.任务状态.colHead')" prop="statusDesc" width="140">
        <template slot-scope="{ row }">
          <icon :class="{
            'rotate-loading': row.isDoing,
          }" style="font-size: 16px; color: var(--color-primary); vertical-align: middle;" svg
            :type="row.statusIconType" />
          <span style="vertical-align: middle;">{{ row.statusDesc }}</span>
        </template>
      </bk-table-column>
      <bk-table-column v-if="allRenderColumnMap.operator" key="operator" align="left" :label="$t('history.执行人.colHead')"
        prop="operator" width="140" />
      <bk-table-column v-if="allRenderColumnMap.createTime" key="createTime" align="left"
        :label="$t('history.开始时间.colHead')" prop="createTime" width="180" />
      <bk-table-column v-if="allRenderColumnMap.totalTimeText" key="totalTimeText" align="right"
        :label="$t('history.耗时时长')" prop="totalTimeText" width="130" />
      <bk-table-column key="action" align="left" fixed="right" :label="$t('history.操作')" width="180">
        <template slot-scope="{ row }">
          <auth-button auth="task_instance/view" :permission="row.canView" :resource-id="row.id" text
            @click="handleGoDetail(row)">
            {{ $t('history.查看详情') }}
          </auth-button>
          <auth-button v-if="!redoRequestMap[row.id]" auth="task_instance/redo" :permission="row.canExecute"
            :resource-id="row.id" text @click="handleGoRetry(row)">
            {{ $t('history.去重做') }}
          </auth-button>
          <span v-else class="task-redo-loading ml10" :data-text="$t('history.去重做')">
            <icon class="rotate-loading" svg type="sync-pending" />
          </span>
          <bk-button text @click="handleToModify(row)" :style="{ color: 'red' }">修改模板</bk-button>
        </template>
      </bk-table-column>
      <bk-table-column type="setting">
        <bk-table-setting-content :fields="tableColumn" :selected="selectedTableColumn" :size="tableSize"
          @setting-change="handleSettingChange" />
      </bk-table-column>
    </render-list>
  </div>
</template>
<script>
import NotifyService from '@service/notify';
import TaskExecuteService from '@service/task-execute';

import { prettyDateTimeFormat } from '@utils/assist';
import { listColumnsCache } from '@utils/cache-helper';
import { IPRule } from '@utils/validator';

import JbSearchSelect from '@components/jb-search-select';
import ListActionLayout from '@components/list-action-layout';
import RenderList from '@components/render-list';

import I18n from '@/i18n';

const TABLE_COLUMN_CACHE = 'execute_history_list_columns';

export default {
  name: '',
  components: {
    ListActionLayout,
    RenderList,
    JbSearchSelect,
  },
  data() {
    return {
      showOperation: false,
      searchParams: {
        startTime: '',
        endTime: '',
      },
      defaultDateTime: [
        '', '',
      ],
      selectedTableColumn: [],
      tableSize: 'small',
      redoRequestMap: {},
    };
  },
  computed: {
    isSkeletonLoading() {
      return this.$refs.list.isLoading;
    },
    searchInfoEnable() {
      return !!this.searchParams.taskInstanceId;
    },
    allRenderColumnMap() {
      return this.selectedTableColumn.reduce((result, item) => {
        result[item.id] = true;
        return result;
      }, {});
    },
  },
  created() {
    this.parseDefaultDateTime();
    this.fetchExecutionHistoryList = TaskExecuteService.fetchExecutionHistoryList;
    this.searchSelect = [
      {
        name: 'ID',
        id: 'taskInstanceId',
        description: I18n.t('history.将覆盖其它条件'),
        validate(values, item) {
          const validate = values.every(_ => /^(\d*)$/.test(_.name));
          return !validate ? I18n.t('history.ID只支持数字') : true;
        },
      },
      {
        name: I18n.t('history.任务名称.colHead'),
        id: 'taskName',
        default: true,
      },
      {
        name: I18n.t('history.目标 IP'),
        id: 'ip',
        validate(values, item) {
          const validate = values.every(_ => IPRule.validator(_.name));
          return !validate ? IPRule.message : true;
        },
      },
      {
        name: I18n.t('history.执行耗时'),
        id: 'totalTimeType',
        children: [
          {
            name: '≤ 60s',
            id: 'LESS_THAN_ONE_MINUTE',
          },
          {
            name: '＞60s and ≤ 600s',
            id: 'ONE_MINUTE_TO_TEN_MINUTES',
          },
          {
            name: '＞ 600s',
            id: 'MORE_THAN_TEN_MINUTES',
          },
        ],
      },
      {
        name: I18n.t('history.执行方式.colHead'),
        id: 'startupModes',
        children: [
          {
            name: I18n.t('history.页面执行'),
            id: 1,
          },
          {
            name: I18n.t('history.定时执行'),
            id: 3,
          },
          {
            name: I18n.t('history.API调用'),
            id: 2,
          },
        ],
      },
      {
        name: I18n.t('history.任务类型.colHead'),
        id: 'taskType',
        children: [
          {
            name: I18n.t('history.作业执行'),
            id: 0,
          },
          {
            name: I18n.t('history.脚本执行'),
            id: 1,
          },
          {
            name: I18n.t('history.文件分发'),
            id: 2,
          },
        ],
      },
      {
        name: I18n.t('history.任务状态.colHead'),
        id: 'status',
        children: [
          {
            name: I18n.t('history.等待执行'),
            id: 1,
          },
          {
            name: I18n.t('history.正在执行'),
            id: 2,
          },
          {
            name: I18n.t('history.执行成功'),
            id: 3,
          },
          {
            name: I18n.t('history.执行失败'),
            id: 4,
          },
          {
            name: I18n.t('history.等待确认'),
            id: 7,
          },
          {
            name: I18n.t('history.状态异常'),
            id: 9,
          },
          {
            name: I18n.t('history.强制终止中'),
            id: 10,
          },
          {
            name: I18n.t('history.强制终止成功'),
            id: 11,
          },
          {
            name: I18n.t('history.确认终止'),
            id: 13,
          },
          {
            name: I18n.t('history.被丢弃'),
            id: 14,
          },
        ],
      },
      {
        name: I18n.t('history.执行人.colHead'),
        id: 'operator',
        remoteMethod: NotifyService.fetchUsersOfSearch,
        inputInclude: true,
      },
    ];
    this.shortcuts = [
      {
        text: I18n.t('history.近1小时'),
        value() {
          const end = new Date();
          const start = new Date();
          start.setTime(start.getTime() - 3600000);
          return [
            start, end,
          ];
        },
      },
      {
        text: I18n.t('history.近12小时'),
        value() {
          const end = new Date();
          const start = new Date();
          start.setTime(start.getTime() - 43200000);
          return [
            start, end,
          ];
        },
      },
      {
        text: I18n.t('history.近1天'),
        value() {
          const end = new Date();
          const start = new Date();
          start.setTime(start.getTime() - 86400000);
          return [
            start, end,
          ];
        },
      },
      {
        text: I18n.t('history.近7天'),
        value() {
          const end = new Date();
          const start = new Date();
          start.setTime(start.getTime() - 604800000);
          return [
            start, end,
          ];
        },
      },
    ];
    this.tableColumn = [
      {
        id: 'id',
        label: I18n.t('history.任务 ID'),
        disabled: true,
      },
      {
        id: 'name',
        label: I18n.t('history.任务名称.colHead'),
        disabled: true,
      },
      {
        id: 'startupModeDesc',
        label: I18n.t('history.执行方式.colHead'),
        disabled: true,
      },
      {
        id: 'typeDesc',
        label: I18n.t('history.任务类型.colHead'),
      },
      {
        id: 'statusDesc',
        label: I18n.t('history.任务状态.colHead'),
        disabled: true,
      },
      {
        id: 'operator',
        label: I18n.t('history.执行人.colHead'),
      },
      {
        id: 'createTime',
        label: I18n.t('history.开始时间.colHead'),
      },
      {
        id: 'totalTimeText',
        label: I18n.t('history.耗时时长'),
      },
    ];
    const columnsCache = listColumnsCache.getItem(TABLE_COLUMN_CACHE);
    if (columnsCache) {
      this.selectedTableColumn = Object.freeze(columnsCache.columns);
      this.tableSize = columnsCache.size;
    } else {
      this.selectedTableColumn = Object.freeze([
        { id: 'id' },
        { id: 'name' },
        { id: 'startupModeDesc' },
        { id: 'typeDesc' },
        { id: 'statusDesc' },
        { id: 'operator' },
        { id: 'createTime' },
        { id: 'totalTimeText' },
      ]);
    }
  },
  methods: {
    /**
     * @desc 获取列表数据
     */
    fetchData() {
      this.$refs.list.$emit('onFetch', this.searchParams);
    },
    /**
     * @desc 重做任务
     */
    redoTask(taskInstanceId) {
      TaskExecuteService.redoTask({
        taskInstanceId,
        taskVariables: [],
      }).then(({ taskInstanceId }) => {
        this.$bkMessage({
          theme: 'success',
          message: I18n.t('history.执行成功'),
        });
        this.$router.push({
          name: 'historyTask',
          params: {
            id: taskInstanceId,
          },
        });
      });
    },
    /**
     * @desc 列表默认的执行时间筛选值
     */
    parseDefaultDateTime() {
      const defaultDateTime = [
        '', '',
      ];
      const searchParams = {
        startTime: '',
        endTime: '',
      };

      const currentTime = new Date().getTime();

      if (Object.prototype.hasOwnProperty.call(this.$route.query, 'startTime')) {
        defaultDateTime[0] = this.$route.query.startTime;
      } else {
        defaultDateTime[0] = prettyDateTimeFormat(currentTime - 86400000);
      }

      searchParams.startTime = defaultDateTime[0]; // eslint-disable-line prefer-destructuring

      if (Object.prototype.hasOwnProperty.call(this.$route.query, 'endTime')) {
        defaultDateTime[1] = this.$route.query.endTime;
        searchParams.endTime = this.$route.query.endTime;
      } else {
        defaultDateTime[1] = prettyDateTimeFormat(currentTime);
        searchParams.endTime = '';
      }
      this.defaultDateTime = defaultDateTime;
      this.searchParams = searchParams;
      if (!searchParams.endTime) {
        setTimeout(() => {
          this.setToNowText(this.defaultDateTime);
        });
      }
    },
    /**
     * @desc 自定义表格显示
     */
    handleSettingChange({ fields, size }) {
      this.selectedTableColumn = Object.freeze(fields);
      this.tableSize = size;
      listColumnsCache.setItem(TABLE_COLUMN_CACHE, {
        columns: fields,
        size,
      });
    },
    /**
     * @desc 自定义表格显示
     * @param {Object} params 筛选值
     */
    handleSearch(params) {
      const { startTime, endTime } = this.searchParams;
      this.searchParams = {
        ...params,
        startTime,
        endTime,
      };
      this.fetchData();
    },
    /**
     * @desc 筛选时间
     * @param {Array} date 时间值
     * @param {String} type 选择类型
     */
    handleDateChange(date, type) {
      if (type === 'upToNow') {
        this.setToNowText(date);
      }
      this.searchParams.startTime = date[0];// eslint-disable-line prefer-destructuring
      this.searchParams.endTime = type === 'upToNow' ? '' : date[1];
      this.fetchData();
    },
    /**
     * @desc 日期值显示为至今
     * @param {Array} date 日期值
     */
    setToNowText(date) {
      this.$refs.datePicker.shortcut = {
        text: `${date[0]} ${I18n.t('history.至今')}`,
      };
    },
    /**
     * @desc 调整执行详情页面
     * @param {Object} taskInstance 任务详情
     *
     * 如果作业类型的跳转到作业执行详情，如果不是则跳到步骤执行详情
     */
    handleGoDetail(taskInstance) {
      if (taskInstance.isTask) {
        this.$router.push({
          name: 'historyTask',
          params: {
            id: taskInstance.id,
          },
        });
      } else if (taskInstance.isScript || taskInstance.isFile) {
        this.$router.push({
          name: 'quickLaunchStep',
          params: {
            taskInstanceId: taskInstance.id,
          },
          query: {
            from: 'historyList',
          },
        });
      } else {
        this.$router.push({
          name: 'historyStep',
          params: {
            taskInstanceId: taskInstance.id,
          },
          query: {
            from: 'historyList',
          },
        });
      }
    },
    /**
     * @desc 重做执行任务
     * @param {Object} taskInstance 任务详情
     *
     * 1，作业执行
     *  —— 有变量需要先去变量设置页面设置变量值
     *  —— 没有变量直接重做
     * 2，快速执行脚本
     *  —— 跳转到快速执行脚本页面
     * 3，快速分发文件
     *  —— 跳转到快速分发文件页面
     */
    handleGoRetry(taskInstance) {
      // console.log(`task_manage/edit/${templateId}?from=list`)
      this.$router.push({
        name: 'templateEdit',
        params: {
          id: taskInstance.templateId
        },
        query: {
          from: 'list',
        },
      });
      return false
      // 作业执行
      if (taskInstance.isTask) {
        // 当重做接口比较慢时页面可能存在多个重做请求，避免重复操作需要禁用正在重做的任务操作
        this.redoRequestMap = {
          ...this.redoRequestMap,
          [taskInstance.id]: true,
        };

        // 历史作业任务详情
        TaskExecuteService.fetchTaskInstance({
          id: taskInstance.id,
        }).then(({ variables }) => {
          // 有变量，去设置变量
          if (variables.length > 0) {
            this.redoRequestMap[taskInstance.id] = false;
            this.$router.push({
              name: 'redoTask',
              params: {
                taskInstanceId: taskInstance.id,
              },
            });
            return;
          }
          // 没有变量直接执行
          this.$bkInfo({
            title: I18n.t('history.确认执行？'),
            subTitle: I18n.t('history.该方案未设置全局变量，点击确认将直接执行。'),
            cancelFn: () => {
              this.redoRequestMap[taskInstance.id] = false;
            },
            confirmFn: () => {
              TaskExecuteService.redoTask({
                taskInstanceId: taskInstance.id,
                taskVariables: [],
              }).then(({ taskInstanceId }) => {
                this.$bkMessage({
                  theme: 'success',
                  message: I18n.t('history.执行成功'),
                });
                this.$router.push({
                  name: 'historyTask',
                  params: {
                    id: taskInstanceId,
                  },
                });
              })
                .finally(() => {
                  this.redoRequestMap[taskInstance.id] = false;
                });
            },
          });
        })
          .catch(() => {
            this.redoRequestMap[taskInstance.id] = false;
          });
      }
      // 快速执行脚本
      // 去快速执行脚本页面重做
      if (taskInstance.isScript) {
        this.$router.push({
          name: 'fastExecuteScript',
          params: {
            taskInstanceId: taskInstance.id,
          },
          query: {
            from: 'executiveHistory',
          },
        });
        return;
      }
      // 快速分发文件
      // 去快速执行分发文件页面重做
      if (taskInstance.isFile) {
        this.$router.push({
          name: 'fastPushFile',
          params: {
            taskInstanceId: taskInstance.id,
          },
          query: {
            from: 'executiveHistory',
          },
        });
      }
    },
    handleToModify({ templateId }) {
      // console.log(`task_manage/edit/${templateId}?from=list`)
      this.$router.push({
        name: 'templateEdit',
        params: {
          id: templateId
        },
        query: {
          from: 'list',
        },
      });
    }
  },
};
</script>
<style lang="postcss">
.executive-history-page {
  .task-redo-loading {
    position: relative;
    font-size: 14px;
    color: var(--color-primary);

    &::after {
      z-index: -1;
      text-align: center;
      word-break: keep-all;
      content: attr(data-text);
      opacity: 0%;
    }

    .rotate-loading {
      position: absolute;
      top: 2px;
      left: 50%;
      margin-left: -9px;
    }
  }
}
</style>
